package test;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.lsda.util.Util;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; 
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LsdaTask implements org.quartz.Job, Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 6356488749018168621L;

	private static Logger _log = LoggerFactory.getLogger(LsdaTask.class);
	
	private int id;
	private Timestamp cron_time;
	private int status;
	private int creator;
	private Timestamp create_time;
	private String comments;
	private String name;
	private String cron_expr;
	private int group_id;
	
	public LsdaTask(){
		
	}
	
	public LsdaTask(int id, Timestamp cron_time, int status, 
			int creator, Timestamp create_time, 
			String comments, String name, String cron_expr, int group_id){
		this.id = id;
		this.cron_time = cron_time;
		this.status = status;
		this.creator = creator;
		this.create_time = create_time;
		this.comments = comments;
		this.name = name;
		this.cron_expr = cron_expr;
		this.group_id = group_id;
	}
	
	public int getId(){
		return id;
	}
	
	public void setId(int id){
		this.id = id;
	}
	
	public Timestamp getCronTime(){
		return cron_time;
	}
	
	public void setCronTime(Timestamp cron_time){
		this.cron_time = cron_time;
	}
	
	public int getStatus(){
		return status;
	}
	
	public void setStatus(int status){
		this.status = status;
	}
	
	public int getCreator(){
		return creator;
	}
	
	public void setCreator(int creator){
		this.creator = creator;
	}
	
	public Timestamp getCreateTime(){
		return create_time;
	}
	
	public void setCreateTime(Timestamp create_time){
		this.create_time = create_time;
	}
	
	public String getComments(){
		return comments;
	}
	
	public void setComments(String comments){
		this.comments = comments;
	}
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getCronExpr(){
		return cron_expr;
	}
	
	public void setCronExpr(String cron_expr){
		this.cron_expr = cron_expr;
	}
	
	public int getGroupId(){
		return group_id;
	}
	
	public void setGroupId(int group_id){
		this.group_id = group_id;
	}
	
	public test.Job wrapperJob(int task_id){
		test.Job job = new test.Job(name, comments);
		Connection conn;
		try {
			conn = Util.getConnection();
			String sql_action = "select t.task_id as tid, t.algorithm_id as aid, " +
					"t.orders as ord, t.parameters as par, t.status as status, " +
					"a.name as name, a.parameters as apar, a.description as descr " +
					"from task_seq t, algorithm a " +
					"where t.task_id = " + task_id +
					" and t.algorithm_id = a.algorithm_id order by t.orders ASC" ;

			PreparedStatement ps_action = conn.prepareStatement(sql_action);
			ResultSet rs_action = ps_action.executeQuery();
			while(rs_action.next()){
				String action_name = rs_action.getString("name");
				int action_order = rs_action.getInt("ord");
				String action_para = rs_action.getString("par");
				String algorithm_para = rs_action.getString("apar");
				String[] para_symbol = algorithm_para.split(":");
				String[] para_value = action_para.split(":");
				
				int length = Math.min(para_symbol.length, para_value.length);
				
				String paras = "";
				for(int i = 0 ; i< length; i++){
					paras += "-" + para_symbol[i] + " " + para_value[i] + " ";
				}
				Action act = new Action();
				act.setSubJobId(action_order);
				act.setPrgName(action_name);
				act.setParam(paras.trim());
				job.addAction(act);
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e){
			e.printStackTrace();
		}
		
		return job;
	}
	
	
	public static List<LsdaTask> fetchNewTasksFromDB(){
		List<LsdaTask> tasks = new ArrayList<LsdaTask>();
		try {
			Connection conn = Util.getConnection();
			String sql_task = "select * from task where status = 0";
			PreparedStatement ps_task = conn.prepareStatement(sql_task);
			ResultSet rs_task = ps_task.executeQuery();
			while(rs_task.next()){
				String task_name = rs_task.getString("name");
				int task_id = rs_task.getInt("task_id");
				int creator = rs_task.getInt("creator");
				Timestamp cron_time = rs_task.getTimestamp("cron_time");
				Timestamp create_time = rs_task.getTimestamp("create_time");
				String comments = rs_task.getString("comments");
				String cron_expr = rs_task.getString("cron_expr"); // cron expression, execute every 3 sec
				int group_id = rs_task.getInt("group_id");
				
				int status = 1;
				LsdaTask task = new LsdaTask(task_id, cron_time, status, creator, create_time, comments, task_name, cron_expr, group_id);
				tasks.add(task);
				
				// set task status to "fetched" = 1 in database;
				String set_task_status_to_fetched = "update task set status = 1 where task_id = " + task_id;
				PreparedStatement ps_task_status = conn.prepareStatement(set_task_status_to_fetched);
				ps_task_status.executeUpdate();
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e){
			e.printStackTrace();
		}
		return tasks;
	}
	
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		// TODO Auto-generated method stub
		// Say Hello to the World and display the date/time
        _log.info("Hello World! - " + new Date());
        //JobKey key = context.getJobDetail().getKey();
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        int task_id = dataMap.getInt("taskid");
        test.Job job = wrapperJob(task_id);
        JobRequest jr;
        
        boolean isTest = true;
        
		try {
			if(!isTest){
				//jr = new JobRequest(job);
				//jr.doJob();
			}else{
				List<Action> actions = job.getActions();
				for(Action action : actions){
					System.out.println(" [parameters] : " + action.getParam());
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
